package com.minelx.datamicroscope.querylanguage.data.sql;

import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.minelx.datamicroscope.querylanguage.data.Condition;

import java.util.List;
import java.util.Objects;

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;

public class InProvider implements ConditionProvider {

	private final SQLInListExpr inListExpr;

	InProvider(SQLInListExpr inListExpr) {
		this.inListExpr = inListExpr;
	}

	@Override
	public FieldBelongs left() {
		return FieldBelongs.from(inListExpr.getExpr().toString());
	}

	@Override
	public String right() {
		return inListExpr.getTargetList().stream().map(String::valueOf).collect(joining(","));
	}

	@Override
	public Condition toCondition() {
		String key = left().fieldName();
		List<Object> values = stream(right().split(",")).collect(toList());
		return new InCondition(key, values);
	}

	@Override
	public String literalKind() {
		return "in";
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		InProvider that = (InProvider) o;
		return inListExpr.equals(that.inListExpr);
	}

	@Override
	public int hashCode() {
		return Objects.hash(inListExpr);
	}

	@Override
	public String toString() {
		return "InProvider{" +
				"inListExpr=" + inListExpr +
				'}';
	}

	private static class InCondition implements Condition {

		private final String key;

		private final List<Object> values;

		public InCondition(String key, List<Object> values) {
			this.key = key;
			this.values = values;
		}

		@Override
		public JSONObject toJSON() {
			JSONObject result = new JSONObject();
			result.put("key", key);
			result.put("operator", "in");
			result.put("value", new JSONArray(values));
			return result;
		}
	}
}
